package concurrent;

import java.util.Scanner;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class PausedExecutorService extends ThreadPoolExecutor {

    private volatile boolean isPaused = false;
    private ReentrantLock lock = new ReentrantLock();
    private Condition notPaused = lock.newCondition();

    public PausedExecutorService(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        System.out.println("before");
        while (isPaused){
            try {
                lock.lock();

                notPaused.await();

            } catch (Exception e) {

            }
            finally {
                lock.unlock();
            }
        }

    }
    public void paused(){

        try {
            lock.lock();

            isPaused = true;
            System.err.println("paused");

        } catch (Exception e) {

        }
        finally {
            lock.unlock();
        }

    }
    public void resume(){

        try {
            System.err.println("resume");

            lock.lock();

            isPaused = false;

            notPaused.signalAll();

        } catch (Exception e) {

        }
        finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        PausedExecutorService pausedExecutorService = new PausedExecutorService(2,2,
                0,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10000));

        for (int i = 0; i < 100; i++) {
            pausedExecutorService.submit(()->{
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("run");
            });
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        pausedExecutorService.paused();

        int i;
        while (true){
            i =  new Scanner(System.in).nextInt();
            if (i == 0){
                pausedExecutorService.resume();
            }
        }
    }
}
